package com.ymatou.iapi.optrade.testcase;

import java.util.Arrays;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import com.ymatou.iapi.delivery.parameter.DeliveryInfo;
import com.ymatou.iapi.optrade.parameter.enums.LogisticsTypeEnum;
import com.ymatou.iapi.optrade.parameter.req.DeliverReq;
import com.ymatou.iapi.optrade.parameter.utill.Utils;
import com.ymatou.iapi.optrade.resp.TradingServiceResp;
import com.ymatou.iapi.optrade.service.DeliveryCall;
import com.ymt.core.tool.Logger;
import com.ymt.utils.annotation.TestCase;
import com.ymt.utils.annotation.TestSuite;
import com.ymt.utils.tag.P1;
import com.ymt.utils.tag.P3;
import com.ymttest.business.service.YMTTrading.TradingCallService;
import com.ymttest.business.service.YMTTrading.TradingPlaceOrderCallService;
import com.ymttest.database.sharding.db.sharding.model.AutoReceiveOptDetailPo;
import com.ymttest.database.sharding.db.sharding.model.AutoReceiveOptPo;
import com.ymttest.database.sharding.db.sharding.model.OrderPo;
import com.ymttest.database.sharding.db.sharding.model.OrderStatusLogPo;
import com.ymttest.database.sharding.db.sqlwapper.OrderShardingWapper;
import com.ymttest.utils.TestDataManager;
import com.ymttest.utils.constant.ECode;

/**
 * 发货 FreeMaker Template自动生成代码
 */
@TestSuite
public class Ts_SellerDelivery {

	private static DeliverReq deliverReq;
	private static DeliveryCall deliveryCall;
	private static OrderShardingWapper orderShardingWapper = new OrderShardingWapper();

	@BeforeClass
	public static void setUp() {
		Logger.createResultFile("卖家发货接口");
	}

	@Before
	public void caseUp() {

		deliverReq = new DeliverReq();
		deliveryCall = new DeliveryCall();
	}

	@AfterClass
	public static void tearDown() {
		Logger.generateResult(deliveryCall.getOpurl());
		
		orderShardingWapper.activeDeadCommunicationsLink(orderShardingWapper);
	}

	@After
	public void caseDown() {
		Logger.end();
	}

	/**
	 * 校验自动确认收货时间操作详情表（auto_receive_opt_detail）
	 */
	private void verifyAutoReceiveDetail(boolean isFreeze) {

		long orderId = deliverReq.getOrderId();

		AutoReceiveOptDetailPo actual = orderShardingWapper
				.selectAutoReceiveOptDetailByOrderId(orderId);

		Logger.comment(String.format(
				"验证自动确认收货时间操作详情表（auto_receive_opt_detail）  orderId: %s",
				orderId));

		Logger.verifyEquals(true,
				Utils.calcTimeSpanMin(actual.getAddTime()) < 2,
				"验证数据库AddTime跟系统当前时间差为2分钟内");
		Logger.verifyEquals(true,
				Utils.calcTimeSpanMin(actual.getUpdateTime()) < 2,
				"验证数据库UpdateTime跟系统当前时间差为2分钟内");

		int bizType = 1;
		if (!deliverReq.isShippedByXlobo()) {
			bizType = 2;
		}

		Logger.verifyEquals(orderId, actual.getOrderId(), "验证数据库OrderId");

		Logger.verifyEquals(bizType, actual.getBizType(), "验证数据库BizType");

		Logger.verifyEquals(null, actual.getUnfreezeTime(),
				"验证数据库UnfreezeTime跟系统当前时间差为2分钟内");

		Logger.verifyEquals(isFreeze, actual.getFreeze(), "验证数据库Freeze");

		verifyAutoReceive(isFreeze);

	}
	/**
	 * 校验自动确认收货时间操作表（auto_receive_opt） 
	 */
	private void verifyAutoReceive(boolean isFreeze) {

		long orderId = deliverReq.getOrderId();
		//  自动确认收货时间操作表（auto_receive_opt） 
		AutoReceiveOptPo autoReceiveOptPo = orderShardingWapper
				.selectAutoReceiveOptByOrderId(orderId);

		Logger.comment(String.format(
				"验证自动确认收货时间操作表（auto_receive_opt）  orderId: %s", orderId));

		Logger.verifyEquals(true,
				Utils.calcTimeSpanMin(autoReceiveOptPo.getAddTime()) < 2,
				"验证数据库AddTime跟系统当前时间差为2分钟内");
		Logger.verifyEquals(true,
				Utils.calcTimeSpanMin(autoReceiveOptPo.getUpdateTime()) < 2,
				"验证数据库UpdateTime跟系统当前时间差为2分钟内");

		Logger.verifyEquals(orderId, autoReceiveOptPo.getOrderId(),
				"验证数据库OrderId");
		Logger.verifyEquals(isFreeze, autoReceiveOptPo.getFreeze(),
				"验证数据库Freeze");

		Logger.verifyEquals(true,
				Utils.calcTimeSpanMin(autoReceiveOptPo.getFreezeTime()) < 2,
				"验证数据库FreezeTime跟系统当前时间差为2分钟内");

		/*		Logger.verifyEquals(null, autoReceiveOptPo.getExpectReceiveTime(),
						"验证数据库ExpectReceiveTime");*/

	}
	
	/**
	 * 校验订单表状态，单主状态操作日志表
	 */
	private void verifyOrderStatus(long orderId) {

		// 订单表(order)
		OrderPo ymtOrders = orderShardingWapper.selectOrderbyOrderId(orderId);

		Logger.comment(String.format("验证订单表(order)表 orderId: %s", orderId));

		Logger.verifyEquals(3, ymtOrders.getOrderStatus(), "验证orderStatus");
		Logger.verifyEquals(deliverReq.isShippedByXlobo(),
				ymtOrders.getXloboDelivery(), "验证xloboDelivery");

		Logger.verifyEquals(
				ymtOrders.getLogisticsType() == 7
						&& deliverReq.getSource() == 2,
				ymtOrders.getDomesticDelivery(), "验证domesticDelivery");
		
		Logger.verifyEquals(true,
				Utils.calcTimeSpanMin(ymtOrders.getDeliveryTime()) < 2,
				"验证数据库deliveryTime跟系统当前时间差为2分钟内");
		
		Logger.verifyEquals(deliverReq.getPartialDeliveryStatus(),
				ymtOrders.getPartialDeliveryStatus(), "验证partialDeliveryStatus");

		//订单主状态操作日志表(order_status_log)
		OrderStatusLogPo orderStatusLogPo = orderShardingWapper
				.selectOrderStatusLogByOrderId(orderId);

		Logger.comment("验证订单主状态操作日志表(order_status_log)");

		Logger.verifyEquals("发货", orderStatusLogPo.getMemo(), "验证数据库Memo");
		Logger.verifyEquals(3, orderStatusLogPo.getOrderStatus(),
				"验证数据库OrderStatus");

		Logger.verifyEquals(true,
				Utils.calcTimeSpanMin(orderStatusLogPo.getAddTime()) < 2,
				"验证数据库AddTime跟系统当前时间差为2分钟内");

		Logger.verifyEquals(orderId, orderStatusLogPo.getOrderId(),
				"验证数据库OrderId");
		Logger.verifyEquals(deliverReq.getSellerId(),
				orderStatusLogPo.getOperator(), "验证数据库Operator");
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SellerDelivery_001() {
		Logger.start(true, "卖家贝海直邮发货");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingCallService
					.orderAccept();

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();
			long sellerId = placeOrderResp.getOrderList().get(0).getSellerId();

			Logger.comment("前置数据准备结束");

			// 物流单号
			String DeliverSummary = TestDataManager.randomStr(10);
			
			DeliveryInfo deliveryInfo = new DeliveryInfo();
			 
			deliveryInfo.setBillNo(DeliverSummary);
			deliveryInfo.setYmtExpressCode("Y068");
			deliveryInfo.setExpressName("洋码头官方合作物流（贝海国际速递）");
			
			deliverReq.setDeliveryInfos(Arrays.asList(deliveryInfo));

			// 订单ID
			deliverReq.setOrderId(orderId);

			// 卖家ID
			deliverReq.setSellerId(sellerId);

			deliverReq.setSource(1);

			deliverReq.setShippedByXlobo(true);

			deliveryCall.setData(deliverReq);
			deliveryCall.callService();

			Logger.verifyEquals(200, deliveryCall.getCode(),
					"验证Code");

			// 数据库验证

			verifyOrderStatus(orderId);
			verifyAutoReceiveDetail(true);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SellerDelivery_002() {
		Logger.start(true, "卖家拼邮国际段发货请求成功");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService
					.placeOrderWithLogisticsType(LogisticsTypeEnum.OVERSEAS_DELIVERY);

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();
			long sellerId = placeOrderResp.getOrderList().get(0).getSellerId();
			long userId = placeOrderResp.getUserId();

			TradingCallService.payOrder(userId,
					placeOrderResp.getPayableAmount(),
					placeOrderResp.getTradingId());

			TradingCallService.sellerAcceptOrder(sellerId, orderId);

			Logger.comment("前置数据准备结束");
					
			// 物流单号
			String DeliverSummary = TestDataManager.randomStr(10);

			
			
			DeliveryInfo deliveryInfo = new DeliveryInfo();
			
			deliveryInfo.setBillNo(DeliverSummary);
			deliveryInfo.setYmtExpressCode("Y022");
			deliveryInfo.setExpressName("自动化测试物流");
			deliveryInfo.setDeliverySection(1);
			
			deliverReq.setDeliveryInfos(Arrays.asList(deliveryInfo));

			// 订单ID
			deliverReq.setOrderId(orderId);
			
			// 卖家ID
			deliverReq.setSellerId(sellerId);
			deliverReq.setSource(1);
			deliverReq.setSection(1);

			deliverReq.setShippedByXlobo(false);

			deliveryCall.setData(deliverReq);
			deliveryCall.callService();

			Logger.verifyEquals(200, deliveryCall.getCode(),
					"验证Code");

			// 数据库验证

			verifyOrderStatus(orderId);

			verifyAutoReceiveDetail(true);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SellerDelivery_003() {
		Logger.start(true, "卖家拼邮国际和国内一起发货请求成功");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService
					.placeOrderWithLogisticsType(LogisticsTypeEnum.OVERSEAS_DELIVERY);

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();
			long sellerId = placeOrderResp.getOrderList().get(0).getSellerId();
			long userId = placeOrderResp.getUserId();

			TradingCallService.payOrder(userId,
					placeOrderResp.getPayableAmount(),
					placeOrderResp.getTradingId());

			TradingCallService.sellerAcceptOrder(sellerId, orderId);

			Logger.comment("前置数据准备结束");

			// 物流单号
			String DeliverSummary = TestDataManager.randomStr(10);

			DeliveryInfo deliveryInfo = new DeliveryInfo();

			deliveryInfo.setBillNo(DeliverSummary);
			deliveryInfo.setYmtExpressCode("Y022");
			deliveryInfo.setExpressName("自动化测试物流");

			deliverReq.setDeliveryInfos(Arrays.asList(deliveryInfo));

			// 订单ID
			deliverReq.setOrderId(orderId);

			// 卖家ID
			deliverReq.setSellerId(sellerId);
			deliverReq.setSource(2);
			deliverReq.setSection(3);

			deliverReq.setShippedByXlobo(false);

			deliveryCall.setData(deliverReq);
			deliveryCall.callService();

			Logger.verifyEquals(200, deliveryCall.getCode(),
					"验证Code");

			// 数据库验证
			verifyOrderStatus(orderId);

			verifyAutoReceive(false);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	@Test
	@Category(P3.class)
	@TestCase
	public void Tc_SellerDelivery_004() {
		Logger.start(false, "订单不存在");
		try {
			long orderId = 2001501;
			long sellerId = 288484;

			// 物流单号
			String DeliverSummary = TestDataManager.randomStr(10);

			DeliveryInfo deliveryInfo = new DeliveryInfo();

			deliveryInfo.setBillNo(DeliverSummary);
			deliveryInfo.setYmtExpressCode("Y022");
			deliveryInfo.setExpressName("自动化测试物流");

			deliverReq.setDeliveryInfos(Arrays.asList(deliveryInfo));

			// 订单ID
			deliverReq.setOrderId(orderId);

			// 卖家ID
			deliverReq.setSellerId(sellerId);
			deliverReq.setSource(2);
			deliverReq.setSection(3);

			deliverReq.setShippedByXlobo(false);

			deliveryCall.setData(deliverReq);
			deliveryCall.callService();
			
			Logger.verifyEquals(500, deliveryCall.getCode(),
					"验证Code");
			Logger.verifyIsContains("系统繁忙，请稍后重试",
					deliveryCall.getMsg(), "验证Msg");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SellerDelivery_005() {
		Logger.start(false, "当前订单状态不能发货");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			TradingServiceResp placeOrderResp = TradingCallService.payOrder();

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();
			long sellerId = placeOrderResp.getOrderList().get(0).getSellerId();

			// 物流单号
			String DeliverSummary = TestDataManager.randomStr(10);

			DeliveryInfo deliveryInfo = new DeliveryInfo();

			deliveryInfo.setBillNo(DeliverSummary);
			deliveryInfo.setYmtExpressCode("Y022");
			deliveryInfo.setExpressName("自动化测试物流");

			deliverReq.setDeliveryInfos(Arrays.asList(deliveryInfo));

			// 订单ID
			deliverReq.setOrderId(orderId);

			// 卖家ID
			deliverReq.setSellerId(sellerId);

			deliveryCall.setData(deliverReq);
			deliveryCall.callService();
			Logger.verifyEquals(201, deliveryCall.getCode(),
					"验证Code");
			Logger.verifyEquals("当前状态2不能发货.", deliveryCall.getMsg(), "验证Msg");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	@Test
	@Category(P3.class)
	@TestCase
	public void Tc_SellerDelivery_006() {
		Logger.start(false, "订单为null");
		try {
			long sellerId = 288484;

			// 物流单号
			String DeliverSummary = TestDataManager.randomStr(10);

			DeliveryInfo deliveryInfo = new DeliveryInfo();

			deliveryInfo.setBillNo(DeliverSummary);
			deliveryInfo.setYmtExpressCode("Y022");
			deliveryInfo.setExpressName("自动化测试物流");

			deliverReq.setDeliveryInfos(Arrays.asList(deliveryInfo));

			// 订单ID
			// deliverReq.setOrderId(orderId);
			
			// 卖家ID
			deliverReq.setSellerId(sellerId);

			deliveryCall.setData(deliverReq);
			deliveryCall.callService();
			Logger.verifyEquals(400, deliveryCall.getCode(),
					"验证Code");
			Logger.verifyIsContains(ECode.ERROR400_MSG_9,
					deliveryCall.getMsg(), "验证Msg");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P3.class)
	@TestCase
	public void Tc_SellerDelivery_007() {
		Logger.start(false, "操作id为null");
		try {

			TradingServiceResp placeOrderResp = TradingCallService
					.orderAccept();

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();

			// 物流单号
			String DeliverSummary = TestDataManager.randomStr(10);

			DeliveryInfo deliveryInfo = new DeliveryInfo();

			deliveryInfo.setBillNo(DeliverSummary);
			deliveryInfo.setYmtExpressCode("Y022");
			deliveryInfo.setExpressName("自动化测试物流");

			deliverReq.setDeliveryInfos(Arrays.asList(deliveryInfo));

			// 订单ID
			deliverReq.setOrderId(orderId);

			// 卖家ID
			// deliverReq.setSellerUserId(sellerId);

			deliverReq.setShippedByXlobo(true);

			deliveryCall.setData(deliverReq);
			deliveryCall.callService();

			// 数据库验证
			Logger.verifyEquals(201, deliveryCall.getCode(),
					"验证Code");
			Logger.verifyIsContains(String.format("用户0不是订单%s的所有者", orderId),
					deliveryCall.getMsg(), "验证Msg");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SellerDelivery_008() {
		Logger.start(false, "当前订单为退货退款中,不能发货");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingCallService
					.orderApplyRefund();

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();
			long sellerId = placeOrderResp.getOrderList().get(0).getSellerId();

			Logger.comment("前置数据准备结束");

			// 物流单号
			String DeliverSummary = TestDataManager.randomStr(10);

			DeliveryInfo deliveryInfo = new DeliveryInfo();

			deliveryInfo.setBillNo(DeliverSummary);
			deliveryInfo.setYmtExpressCode("Y022");
			deliveryInfo.setExpressName("自动化测试物流");

			deliverReq.setDeliveryInfos(Arrays.asList(deliveryInfo));

			// 订单ID
			deliverReq.setOrderId(orderId);

			// 卖家ID
			deliverReq.setSellerId(sellerId);

			deliveryCall.setData(deliverReq);
			deliveryCall.callService();
			Logger.verifyEquals(201, deliveryCall.getCode(),
					"验证Code");
			Logger.verifyEquals(ECode.ErrStatusNotMatch,
					deliveryCall.getString("bcode"), "验证bcode");
			Logger.verifyEquals(ECode.FAILED201_MSG_62,
					deliveryCall.getMsg(), "验证Msg");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SellerDelivery_009() {
		Logger.start(false, "该订单已发货,重复发货失败");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingCallService
					.orderDelivery();

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();
			long sellerId = placeOrderResp.getOrderList().get(0).getSellerId();

			Logger.comment("前置数据准备结束");

			// 物流单号
			String DeliverSummary = TestDataManager.randomStr(10);

			DeliveryInfo deliveryInfo = new DeliveryInfo();

			deliveryInfo.setBillNo(DeliverSummary);
			deliveryInfo.setYmtExpressCode("Y022");
			deliveryInfo.setExpressName("自动化测试物流");

			deliverReq.setDeliveryInfos(Arrays.asList(deliveryInfo));

			// 订单ID
			deliverReq.setOrderId(orderId);

			// 卖家ID
			deliverReq.setSellerId(sellerId);

			deliveryCall.setData(deliverReq);
			deliveryCall.callService();
			Logger.verifyEquals(201, deliveryCall.getCode(),
					"验证Code");
			Logger.verifyEquals("106", deliveryCall.getString("bcode"),
					"验证bcode");
			Logger.verifyEquals(orderId + ECode.FAILED201_MSG_66,
					deliveryCall.getMsg(), "验证Msg");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SellerDelivery_010() {
		Logger.start(true, "订单为锁定中,卖家发货失败");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingCallService
					.orderAccept();

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();
			long sellerId = placeOrderResp.getOrderList().get(0).getSellerId();

			TradingCallService.markOrderLock(orderId, 1);

			Logger.comment("前置数据准备结束");

			// 物流单号
			String DeliverSummary = TestDataManager.randomStr(10);

			DeliveryInfo deliveryInfo = new DeliveryInfo();

			deliveryInfo.setBillNo(DeliverSummary);
			deliveryInfo.setYmtExpressCode("Y022");
			deliveryInfo.setExpressName("自动化测试物流");

			deliverReq.setDeliveryInfos(Arrays.asList(deliveryInfo));

			// 订单ID
			deliverReq.setOrderId(orderId);

			// 卖家ID
			deliverReq.setSellerId(sellerId);

			deliverReq.setShippedByXlobo(false);

			deliveryCall.setData(deliverReq);
			deliveryCall.callService();

			Logger.verifyEquals(201, deliveryCall.getCode(),
					"验证Code");

			Logger.verifyEquals(102, deliveryCall.getBCode(), "验证bcode");

			Logger.verifyEquals("该订单已被客服锁定，暂时无法对该订单进行后续操作",
					deliveryCall.getMsg(), "验证msg");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_SellerDelivery_012() {
		Logger.start(true, "多物流单号,卖家发货请求成功");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingCallService
					.orderAccept();

			Long orderId = placeOrderResp.getOrderList().get(0).getOrderId();
			long sellerId = placeOrderResp.getOrderList().get(0).getSellerId();

			Logger.comment("前置数据准备结束");

			// 物流单号
			String DeliverSummary = TestDataManager.randomStr(10);

			DeliveryInfo deliveryInfo = new DeliveryInfo();

			deliveryInfo.setBillNo(DeliverSummary);
			deliveryInfo.setYmtExpressCode("Y022");
			deliveryInfo.setExpressName("自动化测试物流");

			deliverReq.setDeliveryInfos(Arrays.asList(deliveryInfo));

			// 订单ID
			deliverReq.setOrderId(orderId);

			// 卖家ID
			deliverReq.setSellerId(sellerId);

			deliverReq.setShippedByXlobo(false);

			deliveryCall.setData(deliverReq);
			deliveryCall.callService();

			Logger.verifyEquals(200, deliveryCall.getCode(),
					"验证Code");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	@Test
	@Category(P3.class)
	@TestCase
	public void Tc_SellerDelivery_013() {
		Logger.start(false, "物流单号为null");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingCallService
					.orderAccept();

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();
			long sellerId = placeOrderResp.getOrderList().get(0).getSellerId();

			Logger.comment("前置数据准备结束");

			// 物流单号
			//deliverReq.setDeliverSummary(deliverSummary);

			// 订单ID
			deliverReq.setOrderId(orderId);

			// 卖家ID
			deliverReq.setSellerId(sellerId);

			deliveryCall.setData(deliverReq);
			deliveryCall.callService();
			Logger.verifyEquals(400, deliveryCall.getCode(), "验证Code");
			Logger.verifyIsContains("发货信息不能为空", deliveryCall.getMsg(), "验证Msg");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
}
